﻿using AutoMapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WMS.FC.Application.Menu.Interface;
using WMS.FC.Application.System;
using WMS.FC.Domain.DataTransferObject.Menu;
using WMS.FC.Domain.DomainObject.Menu;
using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.Repository;
using WMS.FC.Domain.Service.Menu.Interface;
using WMS.FC.Domain.ValueObject.Menu;

namespace WMS.FC.Application.Menu
{
    public class MenuService : ServiceBase, IMenuService
    {
        protected readonly IAddMenuService addMenuService;
        protected readonly IDeleteMenuService deleteMenuService;
        protected readonly IEditMenuService editMenuService;
        protected readonly IGetAllMenuListService getAllMenuListService;
        protected readonly IGetMenuConfigService getMenuConfigService;
        protected readonly IGetMenuListService getMenuListService;
        protected readonly IGenerateColumnService generateColumnService;
        protected readonly ICopyColumnService copyColumnService;

        public MenuService(
            ILogger<ServiceBase> logger,
            IOptions<WmsSettings> options,
            IMapper mapper,
            IUnitOfWork unitOfWork,
            IGetMenuListService getMenuListService,
            IAddMenuService addMenuService,
            IDeleteMenuService deleteMenuService,
            IEditMenuService editMenuService,
            IGetAllMenuListService getAllMenuListService,
            IGetMenuConfigService getMenuConfigService,
            IGenerateColumnService generateColumnService,
            ICopyColumnService copyColumnService)
            : base(logger, options, mapper, unitOfWork)
        {
            this.getMenuListService = getMenuListService;
            this.addMenuService = addMenuService;
            this.deleteMenuService = deleteMenuService;
            this.editMenuService = editMenuService;
            this.getAllMenuListService = getAllMenuListService;
            this.getMenuConfigService = getMenuConfigService;
            this.generateColumnService = generateColumnService;
            this.copyColumnService = copyColumnService;
        }

        public async Task<ResponseBase> GetMenuList(GetMenuListDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return getMenuListService.GetMenuList(dTO.UserInfo);
                });

                response = response.TransferResult(result, mapper.Map<List<MenuVO>>);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> GetAllMenuList(GetMenuListDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return getAllMenuListService.GetAllMenuList(dTO.UserInfo);
                });

                response = response.TransferResult(result, mapper.Map<List<MenuVO>>);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> GetMenuConfig(GetMenuConfigDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return getMenuConfigService.GetMenuConfig(dTO.MenuId, dTO.UserInfo);
                });

                response = response.TransferResult(result, mapper.Map<MenuConfigVO>);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> AddMenu(AddMenuDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return addMenuService.AddMenu(dTO.ParentId, dTO.UserInfo);
                });

                response = response.TransferResult(result);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> DeleteMenu(DeleteMenuDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return deleteMenuService.DeleteMenu(dTO.MenuId, dTO.UserInfo);
                });

                response = response.TransferResult(result);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> EditMenu(EditMenuDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return editMenuService.EditMenu(mapper.Map<MenuConfigDO>(dTO), dTO.UserInfo);
                });

                response = response.TransferResult(result);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> GenerateColumns(GenerateColumnDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return generateColumnService.GenerateColumn(dTO.Sql, dTO.UserInfo);
                });

                response = response.TransferResult(result, mapper.Map<List<ColumnVO>>);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }

        public async Task<ResponseBase> CopyColumns(CopyColumnDTO dTO)
        {
            var response = new ResponseBase();
            try
            {
                var result = await unitOfWork.UseTranAsync(() =>
                {
                    return copyColumnService.CopyColumn(dTO.MenuId, dTO.UserInfo);
                });

                response = response.TransferResult(result, mapper.Map<List<ColumnVO>>);
            }
            catch (Exception ex)
            {
                return response.Exception(ex);
            }

            return response;
        }
    }
}
